package com.zekai.calculator;

import android.nfc.Tag;
import android.util.Log;

import androidx.lifecycle.ViewModelProvider;

import java.math.BigDecimal;
import java.math.MathContext;
import java.text.DecimalFormat;
import java.util.Stack;

public class Calculator {
    //TAG
    private static final String TAG="Calculator";
    //错误标识
    private static boolean errorFlag=false;
    //过大数字标识
    private static boolean tooBigFlag=false;
    private static  MainViewModel viewModel;
    //与MainActivity的viewModel关联
    public static void setViewModel(MainViewModel viewModel){
        Calculator.viewModel=viewModel;
    }



    public static String evaluateExpression(String expression) {
        //将中缀表达式转换为后缀表达式
        //如果表达式只有运算符，返回错误
        expression=handleOnlyOperator(expression);
        Log.d(TAG+"HandleOnlyOperator",expression);
        //处理表达式中的阶乘
        expression=handleFactorial(expression);
        Log.d(TAG+"HandleFactorial",expression);
        //处理表达式中的根号
        expression=handleSqrt(expression);
        Log.d(TAG+"HandleSqrt",expression);
        //处理百分号%
        expression=handlePercent(expression);
        //处理表达式中的特殊常量比如e和π
        expression=handleConstant(expression);
        Log.d(TAG+"HandleConstant",expression);
        //如果最后一个字符是运算符，删除最后一个字符
        expression=handleLastOperator(expression);
        //处理括号里面没有内容的情况
        expression=handleEmptyBracket(expression);
        //处理带负号的表达式
        expression=handleNegativeExpression(expression);
        Log.d(TAG+"HandleNegative",expression);
        //处理表达式中左括号前面没有运算符和右括号后面没有运算符但是有数字的情况
        expression=handleBracket(expression);
        Log.d(TAG+"HandleBracket",expression);
        //如果最后一个字符是运算符，删除最后一个字符
        expression=handleLastOperator(expression);
        Log.d(TAG+"HandleLastOperator",expression);
        //如果有错误，返回错误
        if(expression.equals("error")||errorFlag){
            //清空错误标识
            errorFlag=false;
            return "错误";
        }

        String postfixExpression = infixToPostfix(expression);
        String result=String.valueOf(evaluatePostfix(postfixExpression));
//        result=handleDecimal(result);
        Log.d(TAG+"postfix-expression",postfixExpression);
        Log.d(TAG+"final-value",String.valueOf(evaluatePostfix(postfixExpression)));
        if(tooBigFlag){
            //清空过大标识
            tooBigFlag=false;
            return "当前值过大";
        }
        if(errorFlag){
            //清空错误标识
            errorFlag=false;
            return "错误";
        }

        return String.valueOf(result);
    }
    //将中缀表达式转换为后缀表达式
    /*
     * 1.遍历中缀表达式的每个字符
     * 2.如果是数字，需要先分析出完整的数字，直接送入后缀表达式
     * 完整的数字：需要判断位数，是否包含负号
     * 3.如果是左括号，入栈(左括号入栈之后优先级降至最低)
     * 4.如果是右括号，出栈，并将出栈的运算符送入后缀表达式，直到遇到左括号(左括号出栈，但不送入后缀表达式)
     * 总结：只要满足栈顶为左括号即可进行最后一次出栈
     * 5.如果是运算符：(需要判断是否是完整的运算符，比如sin,cos,tan,ln,log)
     * 5.1.如果栈为空，直接入栈
     * 5.2.如果栈不为空，比较栈顶运算符和当前运算符的优先级：
     * 5.2.1.如果栈顶运算符优先级高于或等于当前运算符，出栈，并将出栈的运算符送入后缀表达式，直到栈顶运算符优先级低于当前运算符，或者栈为空，最后将当前运算符入栈
     * 5.2.2.如果栈顶运算符优先级低于当前运算符，直接入栈
     * 总结：只要满足栈空或者优先级高于栈顶运算符即可停止出栈，并将当前运算符入栈
     * 重复以上步骤，直到遍历完中缀表达式接着判断栈是否为空，如果不为空，将栈中剩余的运算符出栈，送入后缀表达式
     */
    private static String infixToPostfix(String infixExpression) {
        StringBuilder postfixExpression = new StringBuilder();
        Stack<String> operatorStack = new Stack<>();

        for (int i = 0; i < infixExpression.length(); i++) {
            char currentChar = infixExpression.charAt(i);
            //如果是数字，需要先分析出完整的数字，直接送入后缀表达式
            if (Character.isDigit(currentChar) || currentChar == '.') {
                // 分析出完整的数字
                //完整的数字：需要判断位数，是否包含负号
                StringBuilder operand = new StringBuilder();
                while (i < infixExpression.length() &&
                        (Character.isDigit(infixExpression.charAt(i)) ||
                                infixExpression.charAt(i) == '.')) {
                    operand.append(infixExpression.charAt(i));
                    i++;
                }
                i--; // 回退一个字符，因为for循环中有i++

                // 将数字送入后缀表达式
                postfixExpression.append(operand).append(" ");
            } else if (currentChar == '(') {
                // 左括号直接入栈
                operatorStack.push(String.valueOf(currentChar));
            } else if (currentChar == ')') {
                // 右括号，出栈并将运算符送入后缀表达式，直到遇到左括号
                while (!operatorStack.isEmpty() && !operatorStack.peek().equals("(")) {
                    postfixExpression.append(operatorStack.pop()).append(" ");
                }
                if (!operatorStack.isEmpty() && operatorStack.peek().equals("(")) {
                    operatorStack.pop(); // 弹出左括号
                }
            }
            // 运算符处理(字符或者+-*/^,需要判断是否是完整的运算符，比如sin,cos,tan,ln,log)
            else if (Character.isLetter(currentChar)) {
                //先分析出完整的运算符
                StringBuilder operator = new StringBuilder();
                while (i < infixExpression.length() && Character.isLetter(infixExpression.charAt(i))) {
                    operator.append(infixExpression.charAt(i));
                    i++;
                };
                i--; // 回退一个字符，因为for循环中有i++
                Log.d(TAG+"operator",operator.toString());
                //如果栈为空，直接入栈(整个运算符入栈)
                if (operatorStack.isEmpty()) {
                    operatorStack.push(operator.toString());
                }

                //如果当前栈顶是左括号，直接入栈
                else if(operatorStack.peek().equals("(")){
                    operatorStack.push(String.valueOf((operator.charAt(0))));
                }
                //当前运算符和栈顶运算符比较优先级
                else {
                    //如果栈顶运算符优先级高于或等于当前运算符，出栈，并将出栈的运算符送入后缀表达式，直到栈顶运算符优先级低于当前运算符，或者栈为空，最后将当前运算符入栈
                    //注意：以前是：这里必须是currentChar是否大于等于operatorStack.peek()，否则会出现栈顶运算符和当前运算符相同的情况确不会出栈,所以这里比较的顺序是相反的，因为hasHigherPrecedence只有大于没有等于
                    //注意：现在是：这里必须是operatorStack.peek()是否大于等于currentChar，因为现在hasHigherPrecedence是大于等于
                    //运算符栈非空,且当前字符不优先于栈顶字符,且栈顶字符不为左括号(
                    while (!operatorStack.isEmpty() && hasHigherPrecedence(operatorStack.peek(),operator.toString())&&!operatorStack.peek().equals("(")){
                        //运算符出栈送入后缀表达式
                        postfixExpression.append(operatorStack.pop()).append(" ");
                    }
                    //如果是当前栈顶是左括号
                    if(!operatorStack.isEmpty()&&String.valueOf(operatorStack.peek()).equals("(")){
                        //当前运算符入栈
                        operatorStack.push(operator.toString());
                    }else{
                        //如果栈顶运算符优先级低于当前运算符，直接入栈
                        operatorStack.push(operator.toString());
                    }
                }


            } else if (isOperator(currentChar)) {
                Log.d(TAG+"operator",String.valueOf(currentChar));
                //如果是运算符，需要判断是否是完整的运算符，比如sin,cos,tan,ln,log
                //如果栈为空，直接入栈
                if (operatorStack.isEmpty()) {
                    operatorStack.push(String.valueOf(currentChar));
                }
                //如果当前栈顶是左括号，直接入栈
                else if(operatorStack.peek().equals("(")){
                    operatorStack.push(String.valueOf(currentChar));
                }
                //当前运算符和栈顶运算符比较优先级
                else {
                    //如果栈顶运算符优先级高于或等于当前运算符，出栈，并将出栈的运算符送入后缀表达式，直到栈顶运算符优先级低于当前运算符，或者栈为空，最后将当前运算符入栈
                    //注意：以前是：这里必须是currentChar是否大于等于operatorStack.peek()，否则会出现栈顶运算符和当前运算符相同的情况确不会出栈,所以这里比较的顺序是相反的，因为hasHigherPrecedence只有大于没有等于
                    //注意：现在是：这里必须是operatorStack.peek()是否大于等于currentChar，因为现在hasHigherPrecedence是大于等于
                    //运算符栈非空,且当前字符不优先于栈顶字符,且栈顶字符不为左括号(
                    while (!operatorStack.isEmpty() && hasHigherPrecedence(operatorStack.peek(),String.valueOf(currentChar))&&!operatorStack.peek().equals("(")){
                        //运算符出栈送入后缀表达式
                        postfixExpression.append(operatorStack.pop()).append(" ");
                    }
                    //如果是当前栈顶是左括号
                    if(!operatorStack.isEmpty()&&String.valueOf(operatorStack.peek()).equals("(")){
                        //当前运算符入栈
                        operatorStack.push(String.valueOf(currentChar));
                    }else{
                        //如果栈顶运算符优先级低于当前运算符，直接入栈
                        operatorStack.push(String.valueOf(currentChar));
                    }


                }

            }
        }

        // 将栈中剩余的运算符送入后缀表达式
        while (!operatorStack.isEmpty()) {
            postfixExpression.append(operatorStack.pop()).append(" ");
        }

        // 返回后缀表达式的字符串形式
        return postfixExpression.toString().trim();
    }




    //计算后缀表达式
    /*
     * 1.遍历后缀表达式的每个字符
     * 2.如果是数字，需要先分析出完整的数字，直接入栈
     * 3.如果是运算符，出栈两个数字，计算结果，入栈
     * 4.重复以上步骤，直到遍历完后缀表达式，最后栈中只有一个数字，即为结果
     */

    private static double evaluatePostfix(String postfixExpression) {
        //运算数栈
        Stack<Double> operandStack = new Stack<>();


        for (int i = 0; i < postfixExpression.length(); i++) {
            char currentChar = postfixExpression.charAt(i);
            //如果是数字，需要先分析出完整的数字，直接入栈
            if (Character.isDigit(currentChar) || currentChar == '.') {
                // 分析出完整的数字
                StringBuilder operand = new StringBuilder();
                while (i < postfixExpression.length() && (Character.isDigit(postfixExpression.charAt(i)) || postfixExpression.charAt(i) == '.')) {
                    operand.append(postfixExpression.charAt(i));
                    i++;
                }
                i--; // 回退一个字符，因为for循环中有i++

                // 将数字送入运算数栈
                operandStack.push(Double.parseDouble(operand.toString()));
            }
            //如果是空格，跳过
            else if (currentChar == ' ') {
                continue;
            }
            else if (Character.isLetter(currentChar)) {
                //先分析出完整的运算符
                StringBuilder operator = new StringBuilder();
                while (i < postfixExpression.length() && Character.isLetter(postfixExpression.charAt(i))) {
                    operator.append(postfixExpression.charAt(i));
                    i++;
                };
                i--; // 回退一个字符，因为for循环中有i++
                Log.d(TAG+"运算符：",operator.toString());
                //如果是一元运算符
                if(isUnaryOperator(operator.toString())){
                    Log.d(TAG+"一元运算符1",operator.toString());
                    //出栈一个数字
                    double operand1 = operandStack.pop();
                    //计算结果
                    double result = performOperation1(operand1, operator.toString());
                    //入栈
                    operandStack.push(result);
                }
                //如果是二元运算符
                else {
                    Log.d(TAG+"二元运算符1",operator.toString());
                    if(operandStack.size()<2){
                        errorFlag=true;
                        return 0;
                    }
                    //出栈两个数字
                    double operand2 = operandStack.pop();
                    double operand1 = operandStack.pop();
                    //计算结果
                    double result = performOperation2(operand1, operand2, operator.toString().charAt(0));
                    //入栈
                    operandStack.push(result);
                }

            }
            //如果是运算符，出栈，计算结果，入栈
            else if (isOperator(currentChar)||isOperater(String.valueOf(currentChar))) {
                Log.d(TAG+"运算符2",String.valueOf(currentChar));
                // 运算符处理
                //判断是一元运算符还是二元运算符
                //如果是一元运算符
                if(isUnaryOperator(String.valueOf(currentChar))){
                    Log.d(TAG+"一元运算符2",String.valueOf(currentChar));
                    if(operandStack.size()<1){
                        errorFlag=true;
                        return 0;
                    }
                    //出栈一个数字
                    double operand1 = operandStack.pop();
                    //计算结果
                    double result = performOperation1(operand1, String.valueOf(currentChar));
                    //入栈
                    operandStack.push(result);
                }
                else {
                    //出栈两个数字
                    if(operandStack.size()<2){
                        errorFlag=true;
                        return 0;
                    }
                    double operand2 = operandStack.pop();
                    double operand1 = operandStack.pop();
                    //计算结果
                    double result = performOperation2(operand1, operand2, currentChar);
                    //入栈
                    operandStack.push(result);
                }
            }
        }

        // 返回后缀表达式的字符串形式
        return operandStack.pop();
    }
    //二元运算
    private static double performOperation2(double operand1, double operand2, char operator) {

        switch (operator) {
            case '+':
                return operand1 + operand2;
            case '-':
                return operand1 - operand2;
            case '*':
                double result=Math.round(operand1 * operand2 * 10000000000.0) / 10000000000.0;
                return result;
            case '/':
                if (operand2 == 0) {
                    errorFlag=true;
                    return 0;
                }
                //
                return Math.round(operand1 / operand2 * 10000000000.0) / 10000000000.0;
            case '^':
                //如果底数是0,错误
                if(operand1==0){
                    errorFlag=true;
                    return 0;
                }
                return Math.pow(operand1,operand2);

            default:
                throw new IllegalArgumentException("Unsupported operator: " + operator);
        }
    }
    //一元运算
    private static double performOperation1(double operand, String operator) {
        switch (operator) {
            case "sin":
                //如果是角度制，转换为弧度制
                if(!viewModel.isRad){
                    BigDecimal angleInRadians = new BigDecimal(Math.toRadians(operand));
                    BigDecimal result = new BigDecimal(Math.sin(angleInRadians.doubleValue()), MathContext.DECIMAL128);
                    result=handleDecimal(result);
                    return result.doubleValue();

                }
                return Math.sin(operand);
            case "cos":
                //如果是角度制，转换为弧度制
                if(!viewModel.isRad){
                    BigDecimal angleInRadians = new BigDecimal(Math.toRadians(operand));
                    BigDecimal result = new BigDecimal(Math.cos(angleInRadians.doubleValue()), MathContext.DECIMAL128);
                    result=handleDecimal(result);
                    return result.doubleValue();
                }
                return Math.cos(operand);
            case "tan":
                if(!viewModel.isRad){
                    BigDecimal angleInRadians = new BigDecimal(Math.toRadians(operand));
                    BigDecimal result = new BigDecimal(Math.tan(angleInRadians.doubleValue()), MathContext.DECIMAL128);
                    result=handleDecimal(result);
                    return result.doubleValue();
                }
                return Math.tan(operand);
            case "ln":
                //如果底数是0,错误
                if(operand==0){
                    errorFlag=true;
                    return 0;
                }
                return Math.log(operand);
            case "log":
                //如果底数是0,错误
                if(operand==0){
                    errorFlag=true;
                    return 0;
                }
                return Math.log10(operand);
            case "√":
                //如果底数是0,错误
                if(operand==0){
                    errorFlag=true;
                    return 0;
                }
                return Math.sqrt(operand);
            case "!":
                //如果底数是负数小数,错误
                if(operand<0||operand%1!=0){
                    errorFlag=true;
                    return 0;
                }
                return factorial((int)operand);
            case "%":
                return operand/100;
            case "arcsin":
                //如果当前状态栏是角度制那么返回的结果也是角度制
                if(!viewModel.isRad){
                    return Math.asin(operand)*180/Math.PI;
                }else {
                    return Math.asin(operand);
                }
            case "arccos":
                if(!viewModel.isRad){
                    return Math.acos(operand)*180/Math.PI;
                }else {
                    return Math.acos(operand);
                }
            case "arctan":
                if(!viewModel.isRad){
                    return Math.atan(operand)*180/Math.PI;
                }else {
                    return Math.atan(operand);
                }
            case "arccot":
                if(!viewModel.isRad){
                    return Math.atan(1/operand)*180/Math.PI;
                }else {
                    return Math.atan(1/operand);
                }
            default:
                throw new IllegalArgumentException("Unsupported operator: " + operator);
        }
    }
    //计算阶乘
    public static long factorial(int n) {
        long[] dp = new long[n + 1];
        dp[0] = 1;

        for (int i = 1; i <= n; i++) {
            dp[i] = dp[i - 1] * i;
        }
        //如果n大于25，返回当前值过大
        if(n>25){

            tooBigFlag=true;
            return 0;
        }

        return dp[n];
    }

    //判断是否是运算符
    private static boolean isOperator(char c) {
        return c == '+' ||
                c == '-' ||
                c == '*' ||
                c == '/'||
                c == '^'||
                c == '!'||
                c == '√';
    }
    //判断是否是运算符
    private static boolean isOperater(String s){
        return s.equals("+")||
                s.equals("-")||
                s.equals("*")||
                s.equals("/")||
                s.equals("^")||
                s.equals("!")||
                s.equals("√")||
                s.equals("sin")||
                s.equals("cos")||
                s.equals("tan")||
                s.equals("ln")||
                s.equals("log")||
                s.equals("arcsin")||
                s.equals("arccos")||
                s.equals("arctan")||
                s.equals("arccot");

    }
    //一元运算符
    private static boolean isUnaryOperator(String s){
        return s.equals("sin")||
                s.equals("cos")||
                s.equals("tan")||
                s.equals("ln")||
                s.equals("log")||
                s.equals("√")||
                s.equals("!")||
                s.equals("arcsin")||
                s.equals("arccos")||
                s.equals("arctan")||
                s.equals("arccot");
    }
    //判断postfixExpression是否包含运算符
    private static boolean hasOperator(String postfixExpression){
        return postfixExpression.contains("+")||
                postfixExpression.contains("-")||
                postfixExpression.contains("*")||
                postfixExpression.contains("/");
    }
    //处理只有运算符，返回错误
    public static String handleOnlyOperator(String expression) {
        // 如果表达式中只包含运算符而没有数字，返回错误
        if (!expression.matches(".*[0-9eπ].*")) {
            errorFlag = true;
            return "error";
        }
        return expression;
    }

    //判断运算符优先级
    //如果op1的优先级高于或等于op2的优先级，返回true
    //当前有运算符：+ - * / sqrt sin cos tan ln log ^ !
    //优先级从高到低：^ ! sqrt sin cos tan ln log * / + -
    private static int getPrecedence(String operator) {
        switch (operator) {
            case "+":
            case "-":
                return 1;
            case "*":
            case "/":
                return 2;
            case "^":
            case "sin":
            case "cos":
            case "tan":
            case "ln":
            case "log":
            case "√":
            case "!":
            case "arcsin":
            case "arccos":
            case "arctan":
            case "arccot":
                return 3;
            default:
                return -1;
        }
    }
    //判断运算符优先级
    private static boolean hasHigherPrecedence(String op1, String op2) {
        return getPrecedence(String.valueOf(op1)) >= getPrecedence(String.valueOf(op2));
    }
    //    private static boolean hasHigherPrecedence(char op1, char op2) {
//        return (op1 == '*' || op1 == '/') &&
//                (op2 == '+' || op2 == '-');
//    }
    //处理最后一个字符是运算符的情况
    public static String handleLastOperator(String expression){
        //如果仅仅只有运算符，返回错误
        expression=handleOnlyOperator(expression);
        //如果最后一个字符是运算符且不是阶乘和%，删除最后一个字符
        if(isOperator(expression.charAt(expression.length()-1))&&
                !String.valueOf(expression.charAt(expression.length()-1)).equals("!"))
        {
            expression=expression.substring(0,expression.length()-1);
            //如果删除最后一个字符之后，最后一个字符是运算符，递归调用
            if(isOperator(expression.charAt(expression.length()-1))){
                expression=handleLastOperator(expression);
            }
        }

        //如果最后一个字符是括号且expression中左括号的个数不等于右括号的个数,返回错误
        if(expression.charAt(expression.length()-1)==')'||expression.charAt(expression.length()-1)=='('){
            int leftBracketCount=0;
            int rightBracketCount=0;
            for(int i=0;i<expression.length();i++){
                if(expression.charAt(i)=='('){
                    leftBracketCount++;
                }
                if(expression.charAt(i)==')'){
                    rightBracketCount++;
                }
            }
            if(leftBracketCount!=rightBracketCount){
                errorFlag=true;
                return "error";
            }
        }
        return expression;
    }

    //处理表达式中的负号
    //几种情况：比如-1+2，-1*2，-1/2，-1.2+2，-1.2*2，-1.2/2
    //比如1+-2，1*-2，1/-2，1.2+-2，1.2*-2，1.2/-2
    //比如-1+-2，-1*-2，-1/-2，-1.2+-2，-1.2*-2，-1.2/-2
    //比如1+(-2)，1*(-2)，1/(-2)，1.2+(-2)，1.2*(-2)，1.2/(-2)
    //比如(-1)+(-2)，(-1)*(-2)，(-1)/(-2)，(-1.2)+(-2)，(-1.2)*(-2)，(-1.2)/(-2)
    private static String handleNegativeExpression(String expression) {
        // 负号前面是数字
        expression = expression.replaceAll("(?<=[0-9])\\-", "+(0-1)*");
        // 负号前面是右括号
        expression = expression.replaceAll("(?<=[)])\\-", "+(0-1)*");
        // 负号前面是小数点
        expression = expression.replaceAll("(?<=[.])\\-", "+(0-1)*");
        // 负号前面是左括号
        expression = expression.replaceAll("(?<=[(])\\-", "(0-1)*");
        // 负号前面是运算符+*
        expression = expression.replaceAll("(?<=[+*])\\-", "(0-1)*");
        // 负号前面是除法运算符
        expression = expression.replaceAll("/-([0-9.]+)", "/((0-1)*$1)");
        //负号前面是^
        expression = expression.replaceAll("\\^-([0-9.]+)", "^((0-1)*$1)");
        // 负号是表达式的开头
        expression = expression.replaceAll("^\\-", "(0-1)*");


        return expression;
    }
    //处理表达式中的特殊常量比如e和π
    public static String handleConstant(String expression){
        //处理表达式中的特殊常量比如e和π
        //先处理需要添加乘号的情况
        //比如2π，2e，2π(，2e(，)π，)e，ee,πe,ππ
        //比如前后都需要添加乘号的情况
        //比如2π2，2e2，2π(2，2e(2，)π2，)e2，e2e,π2e,π2π
        //如果前面是数字，括号，e,π，后面是数字，括号，e,π，添加乘号
        expression=expression.replaceAll("(?<=[0-9)eπ])π","*π");
        expression=expression.replaceAll("(?<=[0-9)eπ])e","*e");
        expression=expression.replaceAll("(?<=[0-9)eπ])\\(","*(");
        //如果前面是数字，括号，e,π，后面是数字，括号，e,π，添加乘号
        expression=expression.replaceAll("π(?=[0-9(eπ])","π*");
        expression=expression.replaceAll("e(?=[0-9(eπ])","e*");
        expression=expression.replaceAll("\\)(?=[0-9(eπ])",")*");
        //再替换π和e
        expression=expression.replaceAll("π","3.14159265358979323846");
        expression=expression.replaceAll("e","2.7182818284590452354");

        return expression;
    }
    //处理表达式中的根号
    public static String handleSqrt(String expression){
        //处理表达式中的根号
        //如果根号后面是负数，错误
        if(expression.contains("√-")){
            errorFlag=true;
            return "error";
        }
        //先处理需要添加乘号的情况
        //前面要添加乘号的情况
        //比如2√
        expression=expression.replaceAll("(?<=[0-9.eπ)])√","*√");
        //添加括号的情况，比如√2，替换为√(2)
        expression=expression.replaceAll("(?<=√)[0-9.eπ]+","($0)");
        return expression;
    }
    //对结果中的小数四舍五入如果变成整数，就返回整数
    public static String handleInteger(String result){
        //如果结果是小数，四舍五入保留10位小数
        if(result.contains(".")){
            BigDecimal bigDecimal=new BigDecimal(result);
            result=bigDecimal.setScale(10,BigDecimal.ROUND_HALF_UP).toString();
            //如果结果是整数，就返回整数
            if(result.substring(result.length()-2,result.length()).equals(".0")){
                result=result.substring(0,result.length()-2);
                //舍去小数末尾过多的0，只保留一个0
                result=result.replaceAll("\\.[1-9]","0");
            }
        }
        return result;
    }



    //处理表达式中左括号前面没有运算符和右括号后面没有运算符但是有数字的情况
    public static String handleBracket(String expression){
        //如果左括号前面没有运算符，添加乘号
        if(expression.contains("(")){
            expression=expression.replaceAll("(?<=[0-9)])\\(","*(");
        }
        //如果右括号后面没有运算符但是有数字，添加乘号
        if(expression.contains(")")){
            expression=expression.replaceAll("\\)(?=[0-9(])","\\)*");
        }
        return expression;
    }
    //处理除法运算最后结果中的小数
    //先四舍五入保留10位小数，如果结果和原来一样相差小于0.0000000001，就用现在的结果，否则用原来的结果
    public static BigDecimal handleDecimal(BigDecimal result){
        result= result.setScale(15, BigDecimal.ROUND_HALF_UP);
        //如果是小数且末尾有0，去掉0直到末尾不是0
        if(result.toString().contains(".")&&result.toString().endsWith("0")){
            while (result.toString().endsWith("0")){
                result=result.setScale(result.scale()-1);
            }
        }
        return result;

    }
    //处理%
    public static String handlePercent(String expression){
        //2%2,22%2,2%22,22%22替换为(2/100)*2,(22/100)*2,(2/100)*22,(22/100)*22
        expression=expression.replaceAll("(?<=[0-9.])%([0-9.]+)","*(0.01*$1)");
        //2%,22%替换为2/100,22/100
        expression=expression.replaceAll("(?<=[0-9.])%","/100");
        return expression;
    }
    //处理阶乘
    public static String handleFactorial(String expression){
        //有些阶乘后面需要添加乘号
        //比如2!2替换位2!*(2)
        expression=expression.replaceAll("(?<=[0-9.eπ)])!([0-9.eπ]+)","!*($1)");


        return expression;
    }
    //处理括号里面没有内容的情况
    public static String handleEmptyBracket(String expression){
        //如果括号里面没有内容，返回错误
        if(expression.contains("()")){
            errorFlag=true;
            return "error";
        }
        return expression;
    }


}
